﻿/**  \file шаблон автоуказатель объекта.
 \brief 

*/



#pragma once
 
#include <iostream>
#include <string>
#include <assert.h>

#include "core_api.h"
 
 

template<class T>
class CORE_API PtrAuto
{
private:

	T* m_pointer;

	void operator = (const PtrAuto& a)
	{
		throw std::runtime_error("wrong operation");
	}

	PtrAuto(const T& a)
	{
		throw std::runtime_error("wrong operation");;
	}

	PtrAuto(const T* a)
	{
		throw std::runtime_error("wrong operation");;
	}



public:

	PtrAuto()
	{
		m_pointer = NULL;
	}

	explicit PtrAuto(T* p_new)
	{
		m_pointer = p_new;
	}

	~PtrAuto()
	{
		if(m_pointer)
		{
			delete m_pointer;
			m_pointer = NULL;
		}
	}

	 
 
	inline void reset(T* p_new)
	{
		if(m_pointer)
		{
			delete m_pointer;
			m_pointer = NULL;
		}

		m_pointer = p_new;
	}

	inline T* get() const	throw (std::runtime_error)
	{
		if(!m_pointer)
		{
			throw std::runtime_error("null pointer");
		}

		return m_pointer;
	}

	inline T* operator -> () const throw (std::runtime_error)
	{
		return get();
	}

	inline operator T* () const throw (std::runtime_error) 
	{
		return get();
	}

	inline T* operator*() const
	{
		return get();
	}


	inline bool operator == (const PtrAuto& a) const 
	{
		return m_pointer == a.m_pointer;
	}

	inline bool operator == (const T* a) const 
	{
		return m_pointer == a;
	}

	inline bool operator != (const PtrAuto& a) const 
	{
		return m_pointer != a.m_pointer;
	}

	inline bool operator != (const T* a) const 
	{
		return m_pointer != a;
	}

	inline bool is_null() const 
	{
		return m_pointer != NULL;
	}

	inline operator bool() const 
	{
		return is_null();
	}



};
 
